package com.kayeah82.application.avatar.qq.repository.redis;

import com.kayeah82.application.avatar.qq.model.Avatar;
import com.kayeah82.application.avatar.qq.repository.AvatarRepository;
import com.kayeah82.application.avatar.qq.utils.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Repository;
import org.springframework.util.Base64Utils;
import org.springframework.util.SerializationUtils;

import java.util.Optional;

/**
 * @author kayeah82
 * */
@Repository
class AvatarRepositoryRedis implements AvatarRepository {

    private static final Logger logger = LoggerFactory.getLogger(AvatarRepositoryRedis.class);

    private final RedisTemplate<String, String> redisTemplate;

    @Autowired
    AvatarRepositoryRedis(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    @Async
    public void storeAvatar(String qq, Avatar avatar) {
        byte[] serialized = SerializationUtils.serialize(avatar);
        if (serialized == null) {
            return;
        }
        redisTemplate.opsForValue().set(getRedisKey(qq), Base64Utils.encodeToString(serialized));
        logger.info("store qq[" + qq + "] avatar to redis");
    }

    @Override
    public Optional<Avatar> loadAvatar(String qq) {
        Avatar avatar = null;
        String imageString = redisTemplate.opsForValue().get(getRedisKey(qq));
        if (StringUtils.isNotEmpty(imageString)) {
            byte[] serialized = new byte[0];
            try {
                serialized = Base64Utils.decodeFromString(imageString);
            } catch (IllegalArgumentException e) {
                redisTemplate.delete(getRedisKey(qq));
            }

            if (serialized.length > 0) {
                Object deserialized = SerializationUtils.deserialize(serialized);
                if (deserialized instanceof Avatar) {
                    avatar = (Avatar)deserialized;
                }
            }
        }
        return Optional.ofNullable(avatar);
    }

    private String getRedisKey(String qq) {
        return RedisUtils.getKey("avatar", "qq", qq);
    }

}
